package com.skynet.app.api.auth.aspect;

import com.skynet.app.api.auth.entity.JwtUser;
import com.skynet.app.api.auth.annotation.Log;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

/**
 * @author Skynet
 * @date 2017年11月27日 17:39
 */
@Component
@Aspect
@Slf4j
public class LogAspect {


    @Pointcut("@annotation(com.skynet.app.api.auth.annotation.Log)")
    public void pointCut() {
        // 横切关注点
    }

    @Around("pointCut()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        // 环绕通知：记录日志信息，例如执行方法，执行时间等
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        Log logAnnotation = method.getAnnotation(Log.class);
        String desc = logAnnotation.value();
        Long beginTime = System.currentTimeMillis();
        Object result = joinPoint.proceed();
        Long endTime = System.currentTimeMillis();
        Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        if (principal instanceof JwtUser) {
            JwtUser jwtUser = (JwtUser) principal;
            log.info("【日志记录】操作人：{}；执行方法：{}；描述：{}；执行时间：{}毫秒", jwtUser.getFullName(), method.getName(), desc, (endTime - beginTime));
            return result;
        }
        log.info("【日志记录】操作人：{}；执行方法：{}；描述：{}；执行时间：{}毫秒", principal, method.getName(), desc, (endTime - beginTime));
        return result;
    }

}
